<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;
use Illuminate\Support\Facades\Redis;

class TestBitmap extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'test:bitmap';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Command description';

    /**
     * Create a new command instance.
     *
     * @return void
     */
    public function __construct()
    {
        parent::__construct();
    }

    /**
     * Execute the console command.
     *
     * @return mixed
     */
    public function handle()
    {
        dd($this->gen_coupon());
//        $pipe_result = Redis::pipeline(function($pipe) use(&$current_loop_data, $all_user_openid_key) {
//            foreach ($current_loop_data as $id) {
//                $pipe->hget($all_user_openid_key, $id);
//                $pipe->hdel($all_user_openid_key, $id);
//            }
//        });

        $pipe_result = Redis::pipeline(function($pipe){
//                $pipe->hget($all_user_openid_key, $id);
//                $pipe->hdel($all_user_openid_key, $id);
        });


        //********判断是否在线******************
        //批量设置在线状态
//        $uids = range(1, 500000);
//        foreach($uids as $uid) {
//            Redis::setBit('online', $uid, $uid % 2);
//        }
//        //一个一个获取状态
//        $uids= range(1, 500000);
//        $startTime = microtime(true);
//        foreach($uids as $uid) {
//            echo Redis::getBit('online', $uid) . PHP_EOL;
//        }
//        $endTime = microtime(true);
//        //在我的电脑上，获取50W个用户的状态需要25秒
//        echo "total:" . ($endTime - $startTime) . "s";

//********签到******************
//用户uid
//        $uid = 1;
//
////记录有uid的key
//        $cacheKey = sprintf("sign_%d", $uid);
//
////开始有签到功能的日期
//        $startDate = '2017-01-01';
//
////今天的日期
//        $todayDate = '2017-01-21';
//
////计算offset
//        $startTime = strtotime($startDate);
//        $todayTime = strtotime($todayDate);
//        $offset = floor(($todayTime - $startTime) / 86400);
//
//        echo "今天是第{$offset}天" . PHP_EOL;
//
////签到
////一年一个用户会占用多少空间呢？大约365/8=45.625个字节，好小，有木有被惊呆？
//        Redis::setBit($cacheKey, $offset, 1);
//
////查询签到情况
//        $bitStatus = Redis::getBit($cacheKey, $offset);
//        echo 1 == $bitStatus ? '今天已经签到啦' : '还没有签到呢';
//        echo PHP_EOL;
//
////计算总签到次数
//        echo Redis::bitCount($cacheKey) . PHP_EOL;
//
//        /**
//         * 计算某段时间内的签到次数
//         * 很不幸啊,bitCount虽然提供了start和end参数，但是这个说的是字符串的位置，而不是对应"位"的位置
//         * 幸运的是我们可以通过get命令将value取出来，自己解析。并且这个value不会太大，上面计算过一年一个用户只需要45个字节
//         * 给我们的网站定一个小目标，运行30年，那么一共需要1.31KB(就问你屌不屌？)
//         */
////这是个错误的计算方式
//        echo Redis::bitCount($cacheKey, 0, 20) . PHP_EOL;

        $cacheKey = 'bitmap';
//我们将7,8,10对应的位置设置为1
        Redis::setBit($cacheKey, 6, 1);
        Redis::setBit($cacheKey, 7, 1);
        Redis::setBit($cacheKey, 8, 1);
        Redis::setBit($cacheKey, 10, 1);
        Redis::setBit($cacheKey, 17, 1);

        $value = Redis::get($cacheKey);

        /**
         * 解包(redis返回来的是二进制字符串，我们需要把它解成对应的数字)
         * 关于unpack的用法，如果不了解，大家可以网上搜索学习，改天可以单独写篇文章分享
         */
        $bitmap = unpack('C*', $value);
        $count = 0;
        foreach($bitmap as $key => $number) {
            for($i = 0; $i < 8; $i++) {
                if(($number >> $i & 1) == 1) {
                    $count++;
                }
            }
        }
        dd($count);
        dd(Redis::bitCount($cacheKey,0,1));
    }

    function gen_coupon()
    {
        do {
            $m = mt_rand(0, PHP_INT_MAX);
            $n = mt_rand(0, PHP_INT_MAX);

            $m = base_convert($m, 10, 36);  // 主随机
            $n = base_convert($n, 10, 36);  // 辅随机

            $r = substr($m . $n, 0, 16);
        } while (strlen($r) != 16);
        $r = strtoupper($r);
        $r = str_split($r, 4);
        $r = implode('-', $r);
        return $r;
    }
}
